package com.ginmeta.controller.system;

import cn.dev33.satoken.annotation.SaCheckRole;
import cn.dev33.satoken.secure.SaSecureUtil;
import cn.dev33.satoken.stp.StpUtil;
import com.ginmeta.common.base.AjaxResult;
import com.ginmeta.common.base.BaseController;
import com.ginmeta.common.base.PageResult;
import com.ginmeta.common.config.SystemConfig;
import com.ginmeta.common.enums.StatusEnum;
import com.ginmeta.common.utils.StringUtils;
import com.ginmeta.common.utils.SystemUtils;
import com.ginmeta.common.utils.file.FileUploadUtils;
import com.ginmeta.common.utils.file.MimeTypeUtils;
import com.ginmeta.domain.login.LoginUser;
import com.ginmeta.domain.system.convert.UserConvert;
import com.ginmeta.domain.system.entity.SysUser;
import com.ginmeta.domain.system.entity.SysUserRole;
import com.ginmeta.domain.system.vo.*;
import com.ginmeta.service.system.SysUserRoleService;
import com.ginmeta.service.system.SysUserService;
import com.mybatisflex.core.paginate.Page;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.Date;
import java.util.List;

/**
 * 用户控制层
 *
 * @author GinMeta
 */
@Slf4j
@RequiredArgsConstructor
@RestController
@RequestMapping("/user")
public class SysUserController extends BaseController {

    private final SysUserService sysUserService;

    private final SysUserRoleService sysUserRoleService;

    /**
     * 查询用户列表
     *
     * @param reqVO 参数
     * @return 结果
     */
    @SaCheckRole(value = "admin")
    @GetMapping("/list")
    public PageResult list(UserPageReqVO reqVO) {
        Page<UserDetailRespVO> page = startFlexPage();
        page = sysUserService.selectUserList(reqVO, page);
        return getFlexDataTable(page);
    }

    /**
     * 根据用户id查询用户详情
     *
     * @param userId 用户id
     * @return 结果
     */
    @SaCheckRole("admin")
    @GetMapping("/query/{userId}")
    public AjaxResult query(@PathVariable("userId") Long userId) {
        // 查询用户数据
        SysUser sysUser = sysUserService.getById(userId);
        if (StringUtils.isNotNull(sysUser)) {
            // 查询角色集合
            List<Long> roleIds = sysUserRoleService.queryChain()
                    .from(SysUserRole.class)
                    .where(SysUserRole::getUserId).eq(sysUser.getUserId())
                    .list()
                    .stream()
                    .map(SysUserRole::getRoleId)
                    .toList();
            sysUser.setRoleIds(roleIds);
        }
        // 返回数据
        return AjaxResult.success(sysUser);
    }

    /**
     * 新增用户
     *
     * @param reqVO 参数
     * @return 结果
     */
    @SaCheckRole("admin")
    @PostMapping("/add")
    public AjaxResult add(@RequestBody UserAddReqVO reqVO) {

        // 判断判断昵称是否存在
        if (sysUserService.checkNickNameUnique(reqVO.getNickName())) {
            return AjaxResult.error("昵称'" + reqVO.getNickName() + "'已存在");
        }

        // 判断判断手机号是否存在
        if (StringUtils.isNotBlank(reqVO.getPhone()) && sysUserService.checkPhoneUnique(reqVO.getPhone())) {
            return AjaxResult.error("手机号'" + reqVO.getPhone() + "'已被绑定");
        }

        // 判断判断邮箱是否存在
        if (StringUtils.isNotBlank(reqVO.getEmail()) && sysUserService.checkEmailUnique(reqVO.getEmail())) {
            return AjaxResult.error("邮箱'" + reqVO.getEmail() + "'已被绑定");
        }

        // bean拷贝
        SysUser sysUser = UserConvert.INSTANCE.toSysUser(reqVO);
        sysUser.setPassword(SaSecureUtil.sha256(reqVO.getNewPassword()))
                .setRegistrationDate(new Date());

        boolean result = sysUserService.add(sysUser);
        return getAjaxResult(result);
    }

    /**
     * 修改用户
     *
     * @param reqVO 参数
     * @return 结果
     */
    @SaCheckRole("admin")
    @PutMapping("/edit")
    public AjaxResult edit(@RequestBody UserEditReqVO reqVO) {

        // 查找用户
        SysUser sysUser = sysUserService.getById(reqVO.getUserId());
        if (StringUtils.isNull(sysUser)) {
            return AjaxResult.error("修改失败，操作对象不存在");
        }

        // 判断判断昵称是否存在
        if (sysUserService.checkNickNameUnique(reqVO.getNickName()) && !reqVO.getNickName().equals(sysUser.getNickName())) {
            return AjaxResult.error("昵称'" + reqVO.getNickName() + "'已存在");
        }

        // 判断判断手机号是否存在
        if (StringUtils.isNotBlank(reqVO.getPhone()) && sysUserService.checkPhoneUnique(reqVO.getPhone()) && !reqVO.getPhone().equals(sysUser.getPhone())) {
            return AjaxResult.error("手机号'" + reqVO.getPhone() + "'已被绑定");
        }

        // 判断判断邮箱是否存在
        if (StringUtils.isNotBlank(reqVO.getEmail()) && sysUserService.checkEmailUnique(reqVO.getEmail()) && !reqVO.getEmail().equals(sysUser.getEmail())) {
            return AjaxResult.error("邮箱'" + reqVO.getEmail() + "'已被绑定");
        }

        // bean拷贝
        sysUser = UserConvert.INSTANCE.toSysUser(reqVO);

        boolean result = sysUserService.edit(sysUser);
        return getAjaxResult(result);
    }

    /**
     * 删除用户
     *
     * @param userIds 用户id集合
     * @return 结果
     */
    @SaCheckRole("admin")
    @DeleteMapping("/remove")
    public AjaxResult remove(@RequestParam(value = "userIds", required = false) List<Long> userIds) {
        if (userIds.contains(1L)) {
            return AjaxResult.error("超级管理员不允许删除");
        }
        boolean result = sysUserService.removeByIds(userIds);
        sysUserService.removeUserRoleList(userIds);
        return getAjaxResult(result);
    }

    /**
     * 修改用户信息
     *
     * @param reqVO 参数
     * @return 结果
     */
    @PutMapping("/editIndividualInfo")
    public AjaxResult editIndividualInfo(@RequestBody UserEditIndividualReqVO reqVO) {

        // 昵称
        if (StringUtils.isBlank(reqVO.getNickName())) {
            return AjaxResult.error("昵称不能为空");
        }

        // 登录用户
        LoginUser loginUser = getLoginUser();

        // 判断判断昵称是否存在
        if (sysUserService.checkNickNameUnique(reqVO.getNickName()) && !reqVO.getNickName().equals(loginUser.getUser().getNickName())) {
            return AjaxResult.error("昵称'" + reqVO.getNickName() + "'已存在");
        }

        // 判断判断手机号是否存在
        if (StringUtils.isNotBlank(reqVO.getPhone()) && sysUserService.checkPhoneUnique(reqVO.getPhone()) && !reqVO.getPhone().equals(loginUser.getUser().getPhone())) {
            return AjaxResult.error("手机号'" + reqVO.getPhone() + "'已被绑定");
        }

        // 判断判断邮箱是否存在
        if (StringUtils.isNotBlank(reqVO.getEmail()) && sysUserService.checkEmailUnique(reqVO.getEmail()) && !reqVO.getEmail().equals(loginUser.getUser().getEmail())) {
            return AjaxResult.error("邮箱'" + reqVO.getEmail() + "'已被绑定");
        }

        // bean拷贝
        SysUser user = UserConvert.INSTANCE.toSysUser(reqVO);
        user.setUserId(loginUser.getUser().getUserId());

        // 修改
        boolean result = sysUserService.updateById(user);
        if (result) {
            user = sysUserService.getById(user.getUserId());
            // 更新缓存
            loginUser.setUser(user);
            StpUtil.getSession().set(SystemUtils.LOGIN_USER, loginUser);
        }

        // 返回结果
        return getAjaxResult(result);
    }

    /**
     * 修改密码
     *
     * @param reqVO 参数
     * @return 结果
     */
    @PutMapping("/editPassword")
    public AjaxResult editPassword(@RequestBody UserEditPasswordReqVO reqVO) {

        // 登录用户
        LoginUser loginUser = getLoginUser();

        // 判断旧密码
        SysUser su = sysUserService.getById(loginUser.getUser().getUserId());
        if (!su.getPassword().equals(SaSecureUtil.sha256(reqVO.getOldPassword()))) {
            return AjaxResult.error("原密码错误");
        }

        // 赋值
        SysUser user = SysUser.builder()
                .userId(loginUser.getUser().getUserId())
                .password(SaSecureUtil.sha256(reqVO.getNewPassword()))
                .build();

        // 修改
        boolean result = sysUserService.updateById(user);

        // 返回结果
        return getAjaxResult(result);
    }

    /**
     * 修改用户状态
     *
     * @param userId 用户id
     * @return 结果
     */
    @PutMapping("/updateStatus")
    public AjaxResult updateStatus(@RequestParam("userId") Long userId) {
        // 校验
        if (StringUtils.isNull(userId)) {
            return AjaxResult.error("操作对象不能为空");
        }
        // 查询
        SysUser sysUser = sysUserService.getById(userId);
        if (StringUtils.isNull(sysUser)) {
            return AjaxResult.error("该用户不存在");
        }
        SysUser user = SysUser.builder().userId(userId).build();
        if (StatusEnum.NORMAL.getValue().equals(sysUser.getStatus())) {
            user.setStatus(StatusEnum.DEACTIVATE.getValue());
        } else {
            user.setStatus(StatusEnum.NORMAL.getValue());
        }
        boolean result = sysUserService.updateById(user);
        return getAjaxResult(result);
    }

    /**
     * 头像上传
     *
     * @param file 头像文件
     * @return 结果
     */
    @PostMapping("/avatar")
    public AjaxResult avatar(@RequestParam("avatarFile") MultipartFile file) throws IOException {
        if (!file.isEmpty()) {
            // 登录用户
            LoginUser loginUser = getLoginUser();
            // 上传
            String avatar = FileUploadUtils.upload(SystemConfig.getProfile() + "/avatar", file, MimeTypeUtils.IMAGE_EXTENSION);
            // 赋值
            SysUser sysUser = new SysUser();
            sysUser.setUserId(loginUser.getUser().getUserId()).setAvatar(avatar);
            // 修改头像并判断
            if (sysUserService.updateById(sysUser)) {
                // 更新缓存用户头像
                loginUser.getUser().setAvatar(avatar);
                StpUtil.getSession().set(SystemUtils.LOGIN_USER, loginUser);
                // 返回修改结果
                return AjaxResult.success("修改头像成功", avatar);
            }
        }
        return AjaxResult.error("上传图片异常，请联系管理员");
    }
}
